home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_0799 / 575 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  10.4 KB

  1. From: Kay Roemer <roemer@informatik.uni-frankfurt.de>
  2. Posted-Date: Mon, 25 Oct 93 8:10:32 MEZ
  3. Received-Date: Mon, 25 Oct 93 08:10:32 +0100
  4. Message-Id: <9310250710.AA22270@hera.rbi.informatik.uni-frankfurt.de>
  5. Subject: fselect() ...
  6. To: mint@atari.archive.umich.edu
  7. Date: Mon, 25 Oct 93 8:10:32 MEZ
  8. Mailer: Elm [revision: 70.85]
  9.  
  10. These diffs make Fselect() work for multiple
  11. processes selecting on the same file.
  12.  
  13. The diffs are relative to 1.09 with my sleep()
  14. patches already applied (look at my previous
  15. message, the new Fselect() will only work with
  16. the patched sleep()).
  17.  
  18. Cheers -- Kay.
  19.  
  20. *** ../new/biosfs.c    Fri Oct 22 20:58:26 1993
  21. --- biosfs.c    Mon Sep 13 21:41:28 1993
  22. ***************
  23. *** 1236,1243 ****
  24.           }
  25.           if (tty) {
  26.           /* avoid collisions with other processes */
  27. !             if (!tty->rsel)
  28. !                 tty->rsel = p;
  29.           }
  30.           return 0;
  31.       } else if (mode == O_WRONLY) {
  32. --- 1240,1248 ----
  33.           }
  34.           if (tty) {
  35.           /* avoid collisions with other processes */
  36. !             if (tty->rsel)
  37. !                 return 2; /* collsion */
  38. !             tty->rsel = p;
  39.           }
  40.           return 0;
  41.       } else if (mode == O_WRONLY) {
  42. ***************
  43. *** 1246,1253 ****
  44.               return 1;
  45.           }
  46.           if (tty) {
  47. !             if (!tty->wsel)
  48. !                 tty->wsel = p;
  49.           }
  50.           return 0;
  51.       }
  52. --- 1251,1259 ----
  53.               return 1;
  54.           }
  55.           if (tty) {
  56. !             if (tty->wsel)
  57. !                 return 2; /* collision */
  58. !             tty->wsel = p;
  59.           }
  60.           return 0;
  61.       }
  62. ***************
  63. *** 1482,1489 ****
  64.       if (mousetail - mousehead)
  65.           return 1;    /* input waiting already */
  66.   
  67. !     if (!mousersel)
  68. !         mousersel = p;
  69.       return 0;
  70.   }
  71.   
  72. --- 1488,1496 ----
  73.       if (mousetail - mousehead)
  74.           return 1;    /* input waiting already */
  75.   
  76. !     if (mousersel)
  77. !         return 2; /* collision */
  78. !     mousersel = p;
  79.       return 0;
  80.   }
  81.   
  82. *** ../new/dosfile.c    Fri Oct 22 20:58:26 1993
  83. --- dosfile.c    Fri Oct 22 19:11:58 1993
  84. ***************
  85. *** 11,16 ****
  86. --- 11,19 ----
  87.   static long do_dup P_((int,int));
  88.   static void unselectme P_((PROC *));
  89.   
  90. + /* wait condition for selecting processes which got collisions */
  91. + short select_coll;
  92.   /*
  93.    * first, some utility routines
  94.    */
  95. ***************
  96. *** 274,279 ****
  97. --- 277,284 ----
  98.       if (f->dev) {
  99.           (*f->dev->unselect)(f, (long)p, O_RDONLY);
  100.           (*f->dev->unselect)(f, (long)p, O_WRONLY);
  101. + /* give other processes a chance to select on this file */
  102. +         wake(SELECT_Q, (long)&select_coll);
  103.       }
  104.   
  105.       f->links--;
  106. ***************
  107. *** 957,983 ****
  108.       unsigned timeout;
  109.       long *rfdp, *wfdp, *xfdp;
  110.   {
  111. !     long rfd, wfd;
  112.       long mask, bytes;
  113.       int i, count;
  114.       FILEPTR *f;
  115.       PROC *p;
  116. !     TIMEOUT *t;
  117.       short sr;
  118.   
  119.       if (xfdp)
  120.           *xfdp = 0;
  121.   
  122.       if (rfdp) {
  123. !         rfd = *rfdp; *rfdp = 0;
  124.       }
  125.       else
  126. !         rfd = 0;
  127.       if (wfdp) {
  128. !         wfd = *wfdp; *wfdp = 0;
  129.       }
  130.       else
  131. !         wfd = 0;
  132.   
  133.       TRACE(("Fselect(%u, %lx, %lx)", timeout, rfd, wfd));
  134.       p = curproc;            /* help the optimizer out */
  135. --- 962,988 ----
  136.       unsigned timeout;
  137.       long *rfdp, *wfdp, *xfdp;
  138.   {
  139. !     long rfd, wfd, orfd, owfd;
  140.       long mask, bytes;
  141.       int i, count;
  142.       FILEPTR *f;
  143.       PROC *p;
  144. !     TIMEOUT *t = 0;
  145.       short sr;
  146.   
  147.       if (xfdp)
  148.           *xfdp = 0;
  149.   
  150.       if (rfdp) {
  151. !         orfd = rfd = *rfdp; *rfdp = 0;
  152.       }
  153.       else
  154. !         orfd = rfd = 0;
  155.       if (wfdp) {
  156. !         owfd = wfd = *wfdp; *wfdp = 0;
  157.       }
  158.       else
  159. !         owfd = wfd = 0;
  160.   
  161.       TRACE(("Fselect(%u, %lx, %lx)", timeout, rfd, wfd));
  162.       p = curproc;            /* help the optimizer out */
  163. ***************
  164. *** 985,991 ****
  165.       /* first, validate the masks */
  166.       mask = 1L;
  167.       for (i = 0; i < MAX_OPEN; i++) {
  168. !         if ( ((rfd & mask) || (wfd & mask)) && !(p->handle[i]) ) {
  169.               DEBUG(("Fselect: invalid handle: %d", i));
  170.               return EIHNDL;
  171.           }
  172. --- 990,996 ----
  173.       /* first, validate the masks */
  174.       mask = 1L;
  175.       for (i = 0; i < MAX_OPEN; i++) {
  176. !         if ( ((orfd & mask) || (owfd & mask)) && !(p->handle[i]) ) {
  177.               DEBUG(("Fselect: invalid handle: %d", i));
  178.               return EIHNDL;
  179.           }
  180. ***************
  181. *** 1001,1043 ****
  182.    * closed one of the handles.
  183.    */
  184.   
  185. -     mask = 1L;
  186.       count = 0;
  187.       curproc->wait_cond = (long)wakeselect;        /* flag */
  188.   
  189.       for (i = 0; i < MAX_OPEN; i++) {
  190.           if (rfd & mask) {
  191.               f = p->handle[i];
  192. !             if ((*f->dev->select)(f, (long)p, O_RDONLY)) {
  193.                   count++;
  194.                   *rfdp |= mask;
  195.               }
  196.           }
  197.           if (wfd & mask) {
  198.               f = p->handle[i];
  199. !             if ((*f->dev->select)(f, (long)p, O_WRONLY)) {
  200.                   count++;
  201.                   *wfdp |= mask;
  202.               }
  203.           }
  204.           mask = mask << 1L;
  205.       }
  206.   
  207.       if (count == 0) {
  208. !         /* OK, now let's set a timeout */
  209.   
  210. !         if (timeout) {
  211.               t = addtimeout((long)timeout, unselectme);
  212. -         } else {
  213. -             t = 0;
  214.           }
  215.   
  216.           sr = spl7();
  217.   
  218.       /* curproc->wait_cond changes when data arrives or the timeout happens */
  219.           while (curproc->wait_cond == (long)wakeselect) {
  220.               TRACE(("sleeping in Fselect"));
  221. !             sleep(SELECT_Q, (long)wakeselect);
  222.           }
  223.           spl(sr);
  224.   
  225. --- 1006,1075 ----
  226.    * closed one of the handles.
  227.    */
  228.   
  229.       count = 0;
  230.       curproc->wait_cond = (long)wakeselect;        /* flag */
  231.   
  232. + /* NOTE to the above note: since we can get here several times (in
  233. +  * case of collisions) after we've gone to sleep, we probably cannot
  234. +  * assume the filepointers are valid.
  235. +  * I'm not really sure, because `post_sig' sets curproc->wait_cond
  236. +  * to zero and then we cannot get here after we've gone to sleep. 
  237. +  */
  238. +  
  239. + retry_after_collision:
  240. +     mask = 1L;
  241. +     
  242.       for (i = 0; i < MAX_OPEN; i++) {
  243.           if (rfd & mask) {
  244.               f = p->handle[i];
  245. !             if (f) {
  246. !                 switch ((*f->dev->select)(f, (long)p, O_RDONLY)) {
  247. !                 case 1:
  248.                   count++;
  249.                   *rfdp |= mask;
  250. +                 case 0:
  251. +                 rfd &= ~mask;
  252. +                 }
  253.               }
  254.           }
  255.           if (wfd & mask) {
  256.               f = p->handle[i];
  257. !             if (f) {
  258. !                 switch ((*f->dev->select)(f, (long)p, O_WRONLY)) {
  259. !                 case 1:
  260.                   count++;
  261.                   *wfdp |= mask;
  262. +                 case 0:
  263. +                 wfd &= ~mask;
  264. +                 }
  265.               }
  266.           }
  267.           mask = mask << 1L;
  268.       }
  269.   
  270.       if (count == 0) {
  271. !     /* OK, now let's set a timeout, but only the first time we get here */
  272.   
  273. !         if (!t && timeout) {
  274.               t = addtimeout((long)timeout, unselectme);
  275.           }
  276.   
  277.           sr = spl7();
  278.   
  279.       /* curproc->wait_cond changes when data arrives or the timeout happens */
  280.           while (curproc->wait_cond == (long)wakeselect) {
  281. +             long cond = (rfd || wfd) ? (long)&select_coll
  282. +                          : (long)wakeselect;
  283. +                          
  284.               TRACE(("sleeping in Fselect"));
  285. !             if (sleep(SELECT_Q, cond))
  286. !                 curproc->wait_cond = 0;
  287. !         }
  288. !         if (curproc->wait_cond == (long)&select_coll) {
  289. !             curproc->wait_cond = (long)wakeselect;
  290. !             spl(sr);
  291. !             goto retry_after_collision;
  292.           }
  293.           spl(sr);
  294.   
  295. ***************
  296. *** 1047,1053 ****
  297.       /* OK, let's see what data arrived (if any) */
  298.           mask = 1L;
  299.           for (i = 0; i < MAX_OPEN; i++) {
  300. !             if (rfd & mask) {
  301.                   f = p->handle[i];
  302.                   if (f) {
  303.                       bytes = 1L;
  304. --- 1079,1085 ----
  305.       /* OK, let's see what data arrived (if any) */
  306.           mask = 1L;
  307.           for (i = 0; i < MAX_OPEN; i++) {
  308. !             if (orfd & mask) {
  309.                   f = p->handle[i];
  310.                   if (f) {
  311.                       bytes = 1L;
  312. ***************
  313. *** 1058,1064 ****
  314.                       }
  315.                   }
  316.               }
  317. !             if (wfd & mask) {
  318.                   f = p->handle[i];
  319.                   if (f) {
  320.                       bytes = 1L;
  321. --- 1090,1096 ----
  322.                       }
  323.                   }
  324.               }
  325. !             if (owfd & mask) {
  326.                   f = p->handle[i];
  327.                   if (f) {
  328.                       bytes = 1L;
  329. ***************
  330. *** 1071,1089 ****
  331.               }
  332.               mask = mask << 1L;
  333.           }
  334. !     }
  335.   
  336.       /* at this point, we either have data or a time out */
  337.       /* cancel all the selects */
  338.       mask = 1L;
  339.   
  340.       for (i = 0; i < MAX_OPEN; i++) {
  341. !         if (rfd & mask) {
  342.               f = p->handle[i];
  343.               if (f)
  344.                   (*f->dev->unselect)(f, (long)p, O_RDONLY);
  345.           }
  346. !         if (wfd & mask) {
  347.               f = p->handle[i];
  348.               if (f)
  349.                   (*f->dev->unselect)(f, (long)p, O_WRONLY);
  350. --- 1103,1127 ----
  351.               }
  352.               mask = mask << 1L;
  353.           }
  354. !     } else if (t) {
  355.   
  356. +     /* in case data arrived after a collsion, there
  357. +      * could be a timeout pending even if count > 0
  358. +      */
  359. +         canceltimeout(t);
  360. +     }
  361. +     
  362.       /* at this point, we either have data or a time out */
  363.       /* cancel all the selects */
  364.       mask = 1L;
  365.   
  366.       for (i = 0; i < MAX_OPEN; i++) {
  367. !         if (orfd & mask) {
  368.               f = p->handle[i];
  369.               if (f)
  370.                   (*f->dev->unselect)(f, (long)p, O_RDONLY);
  371.           }
  372. !         if (owfd & mask) {
  373.               f = p->handle[i];
  374.               if (f)
  375.                   (*f->dev->unselect)(f, (long)p, O_WRONLY);
  376. ***************
  377. *** 1091,1096 ****
  378. --- 1129,1138 ----
  379.           mask = mask << 1L;
  380.       }
  381.   
  382. +     /* wake other processes which got a collision */
  383. +     if (orfd || owfd)
  384. +         wake(SELECT_Q, (long)&select_coll);
  385.       TRACE(("Fselect: returning %d", count));
  386.       return count;
  387.   }
  388. *** ../new/pipefs.c    Fri Oct 22 20:58:28 1993
  389. --- pipefs.c    Mon Sep 13 21:44:34 1993
  390. ***************
  391. *** 1010,1018 ****
  392.               return 1;
  393.           }
  394.   
  395. ! /* BUG: multiple selects fail, only the first one works */
  396. !         if (!p->rsel)
  397. !             p->rsel = proc;
  398.           return 0;
  399.       } else if (mode == O_WRONLY) {
  400.           p = (f->flags & O_HEAD) ? this->inp : this->outp;
  401. --- 1010,1018 ----
  402.               return 1;
  403.           }
  404.   
  405. !         if (p->rsel)
  406. !             return 2; /* collision */
  407. !         p->rsel = proc;
  408.           return 0;
  409.       } else if (mode == O_WRONLY) {
  410.           p = (f->flags & O_HEAD) ? this->inp : this->outp;
  411. ***************
  412. *** 1024,1031 ****
  413.           if (j >= PIPESIZ) j = 0;
  414.           if (j != p->head || p->readers <= 0)
  415.               return 1;    /* data may be written */
  416. !         if (!p->wsel)
  417. !             p->wsel = proc;
  418.           return 0;
  419.       }
  420.       return 0;
  421. --- 1024,1032 ----
  422.           if (j >= PIPESIZ) j = 0;
  423.           if (j != p->head || p->readers <= 0)
  424.               return 1;    /* data may be written */
  425. !         if (p->wsel)
  426. !             return 2; /* collsion */
  427. !         p->wsel = proc;
  428.           return 0;
  429.       }
  430.       return 0;
  431. *** ../new/proc.c    Fri Oct 22 20:59:28 1993
  432. --- proc.c    Fri Oct 22 19:58:24 1993
  433. ***************
  434. *** 612,620 ****
  435.   {
  436.       PROC *p = (PROC *)param;
  437.       short s;
  438.       s = spl7();    /* block interrupts */
  439. !     if(p->wait_cond == (long)wakeselect) {
  440.           p->wait_cond = 0;
  441.       }
  442.       if (p->wait_q == SELECT_Q) {
  443. --- 612,622 ----
  444.   {
  445.       PROC *p = (PROC *)param;
  446.       short s;
  447. !     extern short select_coll; /* in dosfile.c */
  448. !     
  449.       s = spl7();    /* block interrupts */
  450. !     if(p->wait_cond == (long)wakeselect ||
  451. !        p->wait_cond == (long)&select_coll) {
  452.           p->wait_cond = 0;
  453.       }
  454.       if (p->wait_q == SELECT_Q) {
  455. *** ../new/signal.c    Fri Oct 22 20:59:36 1993
  456. --- signal.c    Fri Oct 22 20:58:10 1993
  457. ***************
  458. *** 85,93 ****
  459.   
  460.   /* otherwise, make sure the process is awake */
  461.       if (p->wait_q && p->wait_q != READY_Q) {
  462. !         short sr = spl7();
  463. !         if (p->wait_q == SELECT_Q)
  464. !             p->wait_cond = 0;
  465.           rm_q(p->wait_q, p);
  466.           add_q(READY_Q, p);
  467.           spl(sr);
  468. --- 85,91 ----
  469.   
  470.   /* otherwise, make sure the process is awake */
  471.       if (p->wait_q && p->wait_q != READY_Q) {
  472. !         sr = spl7();
  473.           rm_q(p->wait_q, p);
  474.           add_q(READY_Q, p);
  475.           spl(sr);
  476.  
  477.